package com.binguo.wxapi.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.binguo.common.exception.ServiceException;
import com.binguo.common.paymodel.ThreadManager;
import com.binguo.common.util.ImageBase64Util;
import com.binguo.helper.FaceHelper;
import com.binguo.helper.FaceHelperV3;
import com.binguo.model.mapper.FaceMapper;
import com.binguo.model.mapper.PayCardMapper;
import com.binguo.model.mapper.ShopMapper;
import com.binguo.model.model.*;
import com.binguo.model.repository.CashierDeskExtendRepository;
import com.binguo.model.repository.CustomerRepository;
import com.binguo.model.repository.FaceRepository;
import com.binguo.service.CustomerService;
import com.binguo.service.DeviceMsgService;
import com.binguo.socket.service.MenJinSocketService;
import com.binguo.wxapi.vo.FaceVO;
import io.swagger.models.auth.In;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static com.binguo.common.exception.ErrorCode.DELETE_FACE_ERROR;
import static com.binguo.common.exception.ErrorCode.UPLOAD_ERROR;


@Service
public class WxFaceService {

    private static Logger logger = LoggerFactory.getLogger(WxFaceService.class);
    public static String groupId = "138172";

    @Resource
    FaceMapper faceMapper;

    @Resource
    PayCardMapper payCardMapper;

    @Resource
    ShopMapper shopMapper;

    @Autowired
    FaceHelperV3 faceHelperV3;

    @Autowired
    CashierDeskExtendRepository cashierDeskExtendRepository;

    @Autowired
    MenJinSocketService menJinSocketService;

    @Resource
    DeviceMsgService deviceMsgService;

    @Resource
    FaceRepository faceRepository;

    @Resource
    CustomerService customerService;

    @Resource
    CustomerRepository customerRepository;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    public List<FaceVO> getFaceList(Integer customerId) {
        Condition faceExample = new Condition(Face.class);
        faceExample.or().andEqualTo("customerId", customerId);
        faceExample.orderBy("faceurl").desc();

        List<Face> faceList = faceMapper.selectByCondition(faceExample);

        if (faceList != null && faceList.size() > 0) {
            Set<String> faceUrlList = new HashSet<>();

            List<Face> tempFaceList = new ArrayList<>();
            for (Face face : faceList) {

                if (faceUrlList.contains(face.getFaceurl())) {
                    continue;
                } else {
                    faceUrlList.add(face.getFaceurl());
                    tempFaceList.add(face);
                }
            }

            return tempFaceList.stream().map(f ->
                    FaceVO.builder().faceId(f.getFaceid()).faceUrl(f.getFaceurl()).build()
            ).collect(Collectors.toList());
        }

        return null;
    }

    public void delFace(Integer customerId, String faceId) {
        List<Integer> shopIdList = new ArrayList<>();
        try {
            Condition faceExample = new Condition(Face.class);
            faceExample.or().andEqualTo("customerId",customerId).andEqualTo("faceid", faceId);

            List<Face> userFaceList = faceMapper.selectByCondition(faceExample);

            if (userFaceList != null && userFaceList.size() > 0) {
                String faceUrl = userFaceList.get(0).getFaceurl();


                faceExample = new Condition(Face.class);
                faceExample.or().andEqualTo("customerId",customerId).andEqualTo("faceurl", faceUrl);

                userFaceList = faceMapper.selectByCondition(faceExample);

                for (Face face : userFaceList) {
                    boolean result = FaceHelperV3.deleteFace(face.getPersionid(), face.getFaceid());
                    if (result) {
                        logger.info("faceMapper.delFace");
                        faceMapper.deleteByPrimaryKey(face.getId());
//                        String shopId = face.getPersionid().split("_")[0];

                        /*if (FaceHelperV3.intranetShopIdList.containsKey(Integer.valueOf(shopId))) {
                            //百度删除人脸为直接删除用户，需添加回来其他人脸数据
                            Condition userFaceExample = new Condition(Face.class);
                            userFaceExample.or().andEqualTo("customerId",customerId).andLike("persionid", shopId + "%");
                            List<Face> remainFaceList = faceMapper.selectByCondition(userFaceExample);
                            if (remainFaceList != null && remainFaceList.size() > 0) {
                                for (Face temp : remainFaceList) {
                                    FaceHelperV3.addFace(temp.getPersionid(), temp.getFaceurl());
                                }
                            }
                        }*/
                    } else {
//                        throw new ServiceException("删除失败");
                        FaceHelperV3.deletePerson(face.getPersionid());
                        faceMapper.deleteByPrimaryKey(face.getId());
                        logger.info("delFace error: {}, {}", face.getPersionid(), face.getId());
                    }

                    if (face.getPersionid().contains("_")) {
                        String shopId = face.getPersionid().split("_")[0];
                        shopIdList.add(Integer.parseInt(shopId));
                        deviceMsgService.addDeviceMsg(Integer.valueOf(shopId),
                                customerId, "", faceUrl, "0", faceId);
                    }
                }
                ThreadManager.executorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        for (Integer shopId : shopIdList) {
                            RestTemplate restTemplate = new RestTemplate();
                            JSONArray customerArray = new JSONArray();
                            customerArray.add(customerId);
                            JSONObject param = new JSONObject();
                            param.put("customerIDList", customerArray);
                            param.put("shopID", shopId);
                            HttpHeaders DEFAULT_JSON_HEADER = new HttpHeaders();
                            MediaType jsontype = MediaType.APPLICATION_JSON;
                            DEFAULT_JSON_HEADER.setContentType(jsontype);
                            DEFAULT_JSON_HEADER.add("Accept", MediaType.APPLICATION_JSON.toString());

                            HttpEntity<String> entity = new HttpEntity<String>(param.toJSONString(), DEFAULT_JSON_HEADER);

                            restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
                            ResponseEntity<String> resp = restTemplate.postForEntity(
                                    "https://binguoai.com/api/menJinSocket/customerFaceAdd", entity, String.class);

                        }
                    }
                });

            }

        }catch (Exception e){
            logger.info(e.getMessage());
            throw new ServiceException(DELETE_FACE_ERROR);
        }

    }

    public void addFace(Customer customer, String faceUrl) {
        int score = FaceHelperV3.detectFace(0, faceUrl);
        if (score < 70) {
            throw new ServiceException("人脸图片质量不合格");
        }

        //检查是否已经创建过
        Condition tempFaceExample = new Condition(Face.class);
        tempFaceExample.or().andEqualTo("customerId",customer.getId()).andEqualTo("faceurl", faceUrl);
        List<Face> tempFaceList = faceMapper.selectByCondition(tempFaceExample);

        if (tempFaceList != null && tempFaceList.size() > 0) {
            throw new ServiceException("此图片已经添加");
        }

        //检查是否已经创建过
        Condition faceExample = new Condition(Face.class);
        faceExample.or().andEqualTo("customerId", customer.getId());
        List<Face> faceList = faceMapper.selectByCondition(faceExample);

        Condition payCardExample = new Condition(PayCard.class);
        payCardExample.or().andEqualTo("customerid", customer.getId());

        List<PayCard> payCardList = payCardMapper.selectByCondition(payCardExample);

        //创建人脸信息
        try {
            String faceId = null;
            if (faceList != null && faceList.size() > 0) {
                Set<String> shopIdList = new HashSet<>();
                Map<String, Integer> shopFaceCountMap = new HashMap<>();
                faceList.stream().forEach(face -> {
                    String shopId = face.getPersionid().split("_")[0];
                    Shop shop = shopMapper.selectByPrimaryKey(Integer.valueOf(shopId));
                    if (shop != null) {
                        shopIdList.add(shopId);

                        if (shopFaceCountMap.get(shopId) != null) {
                            shopFaceCountMap.put(shopId, shopFaceCountMap.get(shopId) + 1);
                        } else {
                            shopFaceCountMap.put(shopId, 1);
                        }
                    }
                });

                shopFaceCountMap.forEach((s, count) -> {
                    if (count >=5 ) {
                        throw new ServiceException("人脸数量不能超过5张");
                    }
                });

                for (String s : shopIdList) {
                    String tempFaceId = null;
                    if (FaceHelperV3.getPersonBaseInfo(s + "_" + customer.getId()) == null) {
                        tempFaceId = FaceHelperV3.createPerson(s, s + "_" + customer.getId(), faceUrl);
                    } else {
                        tempFaceId = FaceHelperV3.addFace(s + "_" + customer.getId(), faceUrl);
                    }
                    Face temp = new Face();
                    temp.setFaceid(tempFaceId);
                    temp.setCustomerId(customer.getId());
                    temp.setFaceurl(faceUrl);
                    temp.setPersionid(s + "_" + customer.getId());

                    faceMapper.insertSelective(temp);
                    if (tempFaceId != null) {
                        faceId = tempFaceId;
                    }
                }

            } else {
//                faceId = faceHelper.newPerson(faceUrl, personId, groupId);

                if (payCardList != null && payCardList.size() > 0) {
                    Set<String> shopIdList = new HashSet<>();
                    for (PayCard payCard : payCardList) {//每个商户注册一次
                        shopIdList.add(payCard.getShopid().toString());
                    }

                    for (String s : shopIdList) {
                        Shop shop = shopMapper.selectByPrimaryKey(Integer.valueOf(s));

                        if (shop != null) {
                            String tempFaceId = FaceHelperV3.createPerson(s,
                                    s + "_" + customer.getId().toString(),
                                    faceUrl);

                            Face temp = new Face();
                            temp.setFaceid(tempFaceId);
                            temp.setCustomerId(customer.getId());
                            temp.setFaceurl(faceUrl);
                            temp.setPersionid(s + "_" + customer.getId());

                            faceMapper.insertSelective(temp);

                            if (tempFaceId != null) {
                                faceId = tempFaceId;
                            }
                        }
                    }

                } else {
                    throw new ServiceException("请先创建虚拟卡");
                }
            }
           /* if (faceId == null) {
                newPerson = true;
                faceId = faceHelper.newPerson(faceUrl, personId, groupId);
            }*/
            if (faceId == null) {
                throw new ServiceException("添加人脸失败");
            }

        } catch (Exception e) {
            e.printStackTrace();

            throw new ServiceException(UPLOAD_ERROR);
        }

    }

    public void  addFaceNew(Customer customer, String faceUrl){


        //检查是否已经创建过
        Condition tempFaceExample = new Condition(Face.class);
        tempFaceExample.or().andEqualTo("customerId",customer.getId());
        List<Face> tempFaceList = faceMapper.selectByCondition(tempFaceExample);

        List<String> personIdList = new ArrayList<>();
        if (tempFaceList != null && tempFaceList.size() > 0) {
            for (Face face : tempFaceList) {
                personIdList.add(face.getPersionid());
                if (face.getFaceurl().equals(faceUrl)) {
                    return;
                }
            }
        }
        //此图片未创建

        List<PayCard> payCardList = payCardMapper.getShopCard(customer.getId());

        Integer faceScore = null;
        for (PayCard payCard : payCardList) {
            if (faceScore == null) {
                faceScore = FaceHelperV3.detectFace(payCard.getShopid(), faceUrl);
                if (faceScore.intValue() < 70) {
                    throw new ServiceException("人脸图片质量不合格");
                }
            }

            String faceID = null;
            String personId = payCard.getShopid() + "_" + customer.getId();
            if (personIdList.contains(personId)) {
                faceID = FaceHelperV3.addFace(payCard.getShopid() + "_" + customer.getId(), faceUrl);
            } else {
                try {
                    faceID = FaceHelperV3.createPerson(payCard.getShopid().toString(), personId, faceUrl);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println(e.getMessage());

                }

                if (faceID == null) {
                    faceID = FaceHelperV3.addFace(payCard.getShopid() + "_" + customer.getId(), faceUrl);
                }
            }

            if (faceID != null) {
                Face temp = new Face();
                temp.setFaceid(faceID);
                temp.setCustomerId(customer.getId());
                temp.setFaceurl(faceUrl);
                temp.setPersionid(payCard.getShopid() + "_" + customer.getId());
                faceMapper.insertSelective(temp);
                ThreadManager.executorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        RestTemplate restTemplate = new RestTemplate();
                        JSONArray customerArray = new JSONArray();
                        customerArray.add(customer.getId());
                        JSONObject param = new JSONObject();
                        param.put("customerIDList", customerArray);
                        param.put("shopID", payCard.getShopid());
                        HttpHeaders DEFAULT_JSON_HEADER = new HttpHeaders();
                        MediaType jsontype = MediaType.APPLICATION_JSON;
                        DEFAULT_JSON_HEADER.setContentType(jsontype);
                        DEFAULT_JSON_HEADER.add("Accept", MediaType.APPLICATION_JSON.toString());

                        HttpEntity<String> entity = new HttpEntity<String>(param.toJSONString(), DEFAULT_JSON_HEADER);

                        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
                        ResponseEntity<String> resp = restTemplate.postForEntity(
                                "https://binguoai.com/api/menJinSocket/customerFaceAdd", entity, String.class);

                    }
                });
                CustomerExtend customerExtend = customerService.getCustomerExtend(customer.getId(),payCard.getShopid());
                if (customerExtend.getIsAudit().equals(1)) {
                    deviceMsgService.addDeviceMsg(payCard.getShopid(), customer.getId(), customer.getName(), faceUrl, "1", faceID);
                }
            }
        }
    }

    public void addCmsFace(Customer customer, String faceUrl, Integer shopId) {
//        int score = FaceHelperV3.detectFace(shopId, faceUrl);
//        if (score < 70) {
//            throw new ServiceException("人脸图片质量不合格");
//        }

        //检查是否已经创建过
        String persionId = shopId + "_" + customer.getId();
        Condition tempFaceExample = new Condition(Face.class);
        tempFaceExample.or().andEqualTo("persionid", persionId);
        List<Face> faceList = faceMapper.selectByCondition(tempFaceExample);

        String faceID = null;
        if (null == faceList || faceList.size() == 0) {
            faceID = FaceHelperV3.createPerson(shopId.toString(), persionId, faceUrl);
        } else {
            faceID = FaceHelperV3.addFace(persionId, faceUrl);
        }
        if (faceID != null) {
            Face temp = new Face();
            temp.setFaceid(faceID);
            temp.setCustomerId(customer.getId());
            temp.setFaceurl(faceUrl);
            temp.setPersionid(persionId);
            faceMapper.insertSelective(temp);
            deviceMsgService.addDeviceMsg(shopId, customer.getId(), customer.getName(), faceUrl, "1", faceID);
        }
    }

    public void deletCmsFace(Integer customerId,
                             Integer shopId){

        String persionId = shopId + "_" + customerId;
        Condition condition = new Condition(Face.class);
        condition.or().andEqualTo("persionid",persionId);

        List<Face> faceList = faceRepository.findByCondition(condition);

        boolean result = FaceHelperV3.deletePerson(shopId + "_" + customerId);

        if (result) {
            for (Face face : faceList) {
                deviceMsgService.addDeviceMsg(Integer.valueOf(shopId),
                        customerId, "", face.getFaceurl(), "0", face.getFaceid());
            }

            faceMapper.deleteByCondition(condition);
        }
    }

    public void addCmsDeviceMsg(Integer customerId,
                                Integer shopId){

        Customer customer = customerRepository.findById(customerId);

        String persionId = shopId + "_" + customerId;
        Condition condition = new Condition(Face.class);
        condition.or().andEqualTo("persionid",persionId);

        List<Face> faceList = faceRepository.findByCondition(condition);
        for (Face face : faceList){
            deviceMsgService.addDeviceMsg(shopId, customerId, customer.getName(), face.getFaceurl(), "1", face.getFaceid());
        }
    }
}
